package com.tron.dobest.log;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;

@Component
@Aspect
@Slf4j
public class AopLog {

    @Pointcut("execution(* com.tron.dobest.*.TronLogController.*(..))")
    public void tronPointcut() {}

    @Around("tronPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //IP地址
        String ipAddr = getRemoteHost(request);
        //请求路径
        String url = request.getRequestURL().toString();
        //参数
        Object[] args = joinPoint.getArgs();
        //及时器
        final StopWatch watch = new StopWatch();
        //返回结果封装
        final HashMap<String, Object> exceptionResult = new HashMap<>();
        watch.start();
        System.out.println(joinPoint.getSignature().getDeclaringTypeName());
        try {
            log.info(LogPattern.REQUEST_INFO,ipAddr,url,args);
            Object data = joinPoint.proceed();
            watch.stop();
            log.info(LogPattern.RESPONSE_INFO,ipAddr,url,data,watch.getTotalTimeMillis());
            return data;
        } catch (Throwable throwable) {
            final String errorMsg = throwable.getStackTrace()[0].getClassName() + "." + throwable.getStackTrace()[0].getMethodName() + ":" + throwable.getMessage();
            exceptionResult.put("code", 500);
            exceptionResult.put("msg", errorMsg);
            log.error(LogPattern.ERROR,ipAddr,url, errorMsg);
        }
        return exceptionResult;
    }

    /**
     * 获取目标主机的ip
     * @param request
     * @return
     */
    private String getRemoteHost(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }
}
